<script setup lang="ts">
import { toFormValidator } from "@vee-validate/zod";
import * as zod from "zod";
import { Field, ErrorMessage, useForm } from "vee-validate";
import { AuthAPI } from "@/api/AuthAPI";
import { AxiosError } from "axios";
import useCountdown from "@/logics/useCountdown";
import { getCurrentInstance } from "vue";
import { useUserStore } from "@/stores/userStore";

const validationSchema = toFormValidator(
  zod
    .object({
      account: zod
        .string({ required_error: "请输入用户名" })
        .regex(/^[a-zA-Z]\w{5,19}$/, "字母开头且6-20个字符"),
      mobile: zod
        .string({ required_error: "请输入手机号" })
        .regex(/^1[3-9]\d{9}$/, "请输入正确的手机号"),
      code: zod
        .string({ required_error: "请输入验证码" })
        .regex(/^\d{6}$/, "验证码格式错误"),
      password: zod
        .string({ required_error: "请输入密码" })
        .regex(/^\w{6,24}$/, "密码是6-24个字符"),
      confirm: zod.string({ required_error: "请再次输入密码" }),
    })
    .refine((data) => data.password === data.confirm, {
      message: "两次密码输入不一致",
      path: ["confirm"],
    })
);

const checkAccountUnique = zod.string().refine(
  async (account) => {
    const response = await AuthAPI.checkAccountUnique(account);
    return !response.result.valid;
  },
  { message: "用户名已存在" }
);

const { handleSubmit, validateField, setFieldError } = useForm<{
  account: string;
  mobile: string;
  code: string;
  password: string;
}>({
  validationSchema,
});

const userStore = useUserStore();
const props = defineProps<{ unionId: string }>();
const onSubmit = handleSubmit(async (formValues) => {
  try {
    await checkAccountUnique.parseAsync(formValues.account);
    userStore.login(() =>
      AuthAPI.loginByBindNewAccount(props.unionId, formValues)
    );
  } catch (error) {
    if (error instanceof zod.ZodError) {
      setFieldError("account", error.errors[0].message);
    }
  }
});

const $ = getCurrentInstance();
const { start, count, isActive } = useCountdown();

const { values } = useForm();

async function sendMsgCode() {
  let { valid } = await validateField("mobile");
  if (!valid) return;
  if (isActive.value) return;
  try {
    await AuthAPI.sendMsgCodeOfRegister(values.mobile);
    $?.proxy?.$message({ type: "success", msg: "手机验证码发送成功" });
    start(60);
  } catch (error) {
    if (error instanceof AxiosError) {
      $?.proxy?.$message({ type: "error", msg: error.response?.data.message });
    } else {
      $?.proxy?.$message({ type: "error", msg: "手机验证码发送失败" });
    }
  }
}
</script>
<template>
  <form class="xtx-form" @submit.prevent="onSubmit">
    <div class="xtx-form-item">
      <Field as="div" name="account" v-slot="{ field }" class="field">
        <i class="icon iconfont icon-user"></i>
        <input
          v-bind="field"
          class="input"
          type="text"
          placeholder="请输入用户名"
        />
      </Field>
      <ErrorMessage as="div" name="account" class="error"></ErrorMessage>
    </div>
    <div class="xtx-form-item">
      <Field as="div" name="mobile" v-slot="{ field }" class="field">
        <i class="icon iconfont icon-phone"></i>
        <input
          v-bind="field"
          class="input"
          type="text"
          placeholder="请输入手机号"
        />
      </Field>
      <ErrorMessage as="div" name="mobile" class="error"></ErrorMessage>
    </div>
    <div class="xtx-form-item">
      <Field name="code" as="div" v-slot="{ field }" class="field">
        <i class="icon iconfont icon-code"></i>
        <input
          v-bind="field"
          class="input"
          type="text"
          placeholder="请输入验证码"
        />
        <span class="code" @click="sendMsgCode">{{
          isActive ? `剩余${count}秒` : "发送验证码"
        }}</span>
      </Field>
      <ErrorMessage as="div" name="code" class="error"></ErrorMessage>
    </div>
    <div class="xtx-form-item">
      <Field as="div" name="password" v-slot="{ field }" class="field">
        <i class="icon iconfont icon-lock"></i>
        <input
          v-bind="field"
          class="input"
          type="password"
          placeholder="请输入密码"
          autocomplete="on"
        />
      </Field>
      <ErrorMessage as="div" name="password" class="error"></ErrorMessage>
    </div>
    <div class="xtx-form-item">
      <Field as="div" name="confirm" v-slot="{ field }" class="field">
        <i class="icon iconfont icon-lock"></i>
        <input
          v-bind="field"
          class="input"
          type="password"
          placeholder="请确认密码"
          autocomplete="on"
        />
      </Field>
      <ErrorMessage as="div" name="confirm" class="error"></ErrorMessage>
    </div>
    <input type="submit" class="submit" value="立即绑定" />
  </form>
</template>

<style scoped lang="less">
.code {
  position: absolute;
  right: 0;
  top: 0;
  line-height: 50px;
  width: 80px;
  color: #999;
  &:hover {
    cursor: pointer;
  }
}
</style>
